package com.fanshuai.websocket.server;

import com.fanshuai.websocket.annotation.WebSocketMapping;
import com.fanshuai.websocket.frame.Message;
import com.fanshuai.websocket.net.WebFluxChatManager;
import com.fanshuai.websocket.net.WebSocketChannel;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.socket.WebSocketHandler;
import org.springframework.web.reactive.socket.WebSocketSession;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@Service
@WebSocketMapping("/chat")
public class WebFluxChatServer implements WebSocketHandler {
    ObjectMapper mapper = new ObjectMapper();

    @Override
    public Mono<Void> handle(WebSocketSession session) {
        Mono<Void> output = session.send(Flux.create(sink -> {
            WebSocketChannel channel = new WebSocketChannel(session, sink);
            WebFluxChatManager.initChannel(channel);
        }));

        Mono<Void> input = session.receive()
                .flatMap(webSocketMessage -> {
                    return Mono.just(webSocketMessage.getPayloadAsText());
                })
                .doOnNext(messageBody -> {
                    try {
                        Message message1 = mapper.readValue(messageBody, Message.class);
                        String uid = message1.getUid();

                        switch (message1.getType()) {
                            case 1:
                                WebFluxChatManager.addChannel(session, uid);
                                groupSend(uid + "进入直播间");
                                break;
                            case 2:
                                groupSend(uid + "退出直播间");
                                WebFluxChatManager.delChanel(uid);
                                break;
                            case 3:
                                String text = message1.getText();
                                groupSend(uid + ": " + text);
                                break;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }).then();

        return Mono.zip(input, output).then();
    }

    private void groupSend(String message) {
        for (WebSocketChannel channel : WebFluxChatManager.channelMap.values()) {
            try {
                channel.sendData(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
